<?php
/**
 * 商品评价
 * Author: hezhizheng
 * Date: 2018-12-03
 * Created by Panxsoft.
 */

namespace App\Http\Controllers\Api\V1\App\Order;

use App\Http\Controllers\ApiController;
use App\Http\Requests\Order\ReviewStoreRequest;
use App\Http\Requests\Review\ReviewIndexRequest;
use App\Http\Services\Api\V1\App\Product\ReviewService;
use App\Models\Customers\Customer;
use App\Models\Order\Order;
use App\Models\Order\OrderProduct;
use App\Models\Order\OrderStatus;
use App\Models\Products\Review;
use App\Models\Products\ReviewImage;
use App\Services\Utils\Guard;
use App\Services\Utils\ImageHelper;
use App\Services\Utils\Transaction;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;

class ReviewController extends ApiController
{
    private $review;

    public function __construct()
    {
        $this->review = new ReviewService();
    }

    /**
     *  app端 商品订单评价列表
     *
     * @param ReviewIndexRequest $request
     * @return array|\Illuminate\Http\Response
     * @throws \Exception
     */
    public function index(ReviewIndexRequest $request)
    {
        $review_type = $request->review_type;
        $per_page = $request->per_page ?? 10;

        $reviews = $this->review->getReview($review_type, $per_page);

        return $this->response(compact('reviews'));
    }

    /**
     * @param ReviewStoreRequest $request
     * @return array|\Illuminate\Http\Response
     * @throws \Exception
     */
    public function store(ReviewStoreRequest $request)
    {
        $customer = Guard::customer();

        /** @var OrderProduct $orderProduct */
        $orderProduct = (new OrderProduct)->with('order', 'review', 'returnProduct')
            ->find($request->order_product_id);

        $this->checkItemExist($orderProduct);
        $this->checkIsTrue(OrderProduct::canToBeEvaluate($orderProduct), trans('checker.order_not_completed'));
        $this->checkUnless($orderProduct->review, trans('order.review_exist'));
//        $this->checkUnless($orderProduct->returnProduct, trans('order.in_after_sale_can_not_review')); // 评价和退货分开了！

        $review_data = $this->assembleReviewData($orderProduct, $customer, $request);

        $images = $request->images ?: [];
        $store = $this->storeReviewAndImage($review_data, $images);

        return $this->response(compact('store'));
    }

    /**
     * @param OrderProduct $orderProduct
     * @param Customer $customer
     * @param ReviewStoreRequest $request
     * @return array
     */
    private function assembleReviewData(OrderProduct $orderProduct, Customer $customer, ReviewStoreRequest $request)
    {
        $now = (string)Carbon::now();

        $review_data = [
            'product_id'       => $orderProduct->product_id,
            'customer_id'      => $customer->getKey(),
            'order_product_id' => $request->order_product_id,
            'author'           => $customer->fullname,
            'text'             => $request->text,
            'rating'           => $request->rating,
            'date_added'       => $now,
            'date_modified'    => $now,
        ];

        return $review_data;
    }

    /**
     * @param array $review_data
     * @param array $images
     * @return mixed
     * @throws \Exception
     */
    private function storeReviewAndImage(array $review_data, array $images)
    {
        $stored = Transaction::handle(function() use($review_data, $images){
            /** @var Review $store */
            $store = (new Review)->create($review_data);

            $this->storeReviewImage($images, $store->review_id);

            return $store;
        });

        return $stored;
    }

    /**
     * @param array $images
     * @param $review_id
     * @return bool
     */
    private function storeReviewImage(array $images, $review_id)
    {
        if (! count($images)) return true;

        $data = [];
        foreach($images as $review_image)
        {
            $review_image = ImageHelper::deleteHeaderAndParameter($review_image);
            $data[] = ['image' => $review_image, 'review_id' => $review_id];
        }

        (new ReviewImage)->insert($data);
    }
}
